<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .dfList{
            background-color: #fff;
        }
        .dfItem{
            display: flex;
            flex-wrap: nowrap;
            justify-content: flex-start;
            margin-bottom: 10px;
            padding: 4px;
            border-radius: 4px;
            box-shadow: 0 0 4px #333;
        }
        .dfNameCard{
            overflow: hidden;
            padding: 4px;
            width: 200px;
            text-align: center;
            background-color: rgb(98, 136, 9);
            color: #fff;
        }
        .dfSkillCard{
            width: 200px;
            margin-left: 2px;
            padding: 4px;
            background-color: #09f;
            color: #fff;
        }
        .dfItemCard{
            width: 200px;
            margin-left: 2px;
            padding: 4px;
            background-color: rgb(106, 128, 11);
            color: #fff;
        }
        .dfEmoCard{
            width: 300px;
            margin-left: 2px;
            padding: 4px;
            background-color: rgb(231, 34, 67);
            color: #fff;
        }

        .emoDetail{
            overflow: auto;
            box-sizing: border-box;
            max-height: 100px;
        }

        .emoDetail::-webkit-scrollbar{
            width: 6px;
            background-color: rgb(53, 118, 165);
        }
        .emoDetail::-webkit-scrollbar-thumb{
            background-color: rgb(190, 229, 255);
        }
        .emodes{
            max-width: 300px;
            padding-top: 2px;
            overflow-x: auto;
            font-size: 14px;
            white-space: nowrap;
        }
        .emodes::-webkit-scrollbar{
            height: 4px;
            background-color: rgb(53, 118, 165);
        }
        .emodes::-webkit-scrollbar-thumb{
            background-color: rgb(247, 252, 255);
        }
        .skillDetail{
            max-height: 80px;
            overflow: auto;
            box-sizing: border-box;
        }

        .skillDetail::-webkit-scrollbar{
            width: 6px;
            background-color: rgb(53, 118, 165);
        }
        .skillDetail::-webkit-scrollbar-thumb{
            background-color: rgb(190, 229, 255);
        }

        

        .skillType{
            color: rgb(238, 255, 198);
            text-align: center;
            font-weight: 900;
        }
        .btn {
			outline: none;
			background-color: #09f;
			color: #fff;
			padding: 3px;
			border-radius: 2px;
			border: none;
			box-sizing: border-box;
			cursor: pointer;
		}

		.btn:hover {
			background-color: rgb(7, 121, 214);
			transition: background-color 200ms;
		}

		.btn:active {
			background-color: rgb(115, 192, 243);
		}
        .tools{
            display: flex;
            justify-content: left;
            margin: 10px 0 ;

        }
        .toolitem{
            margin-left: 4px;
        }
        .select{
            position: relative;
            border-radius: 4px;
            display: flex;
            box-sizing: border-box;
            box-shadow: 0 0 #333;
            margin: 10px;
        }
        .hide {
            display: none;
        }
        .selectIpt{
            margin-left: 4px;
            box-sizing: border-box;
        }
        .skilldes{
            max-width: 200px;
            overflow-x: auto;
            font-size: 14px;
            white-space: nowrap;
        }
        .skilldes::-webkit-scrollbar{
            height: 4px;
            background-color: rgb(53, 118, 165);
        }
        .skilldes::-webkit-scrollbar-thumb{
            background-color: rgb(247, 252, 255);
        }
    </style>
</head>
<body>
    <div>
        <div class="tools">
            <div id="counts"></div>
            <div id="lack"></div>
            <button class="btn toolitem" id="hideItems">隐藏物品</button>
            <button class="btn toolitem" id="hideSkill">隐藏技能</button>
            <button class="btn toolitem" id="hideEmo">隐藏emo</button>
            <button class="btn toolitem" id="sortName">按名称排序</button>
            <button class="btn toolitem" id="sortStress">按心情排序</button>
            <button class="btn toolitem" id="sortage">按年龄排序</button>
            <button class="btn toolitem" id="sortfight">按军事技能排序</button>
            <button class="btn toolitem" id="sortsmelt">盔甲武器锻造</button>
            <div class="select">
                <div id="sel"></div>
                按<input id="normal" class="selectIpt"/>
                <button id="sortSkill" class="btn">排序</button>
            </div>
            

        </div>

        <div id="dfList" class="dfList">

        </div>

    </div>



    <script>
        let Enums = {
            remembered_reflected_on: "回想",
            remembered_shortterm:"短期记忆",
            EMBARRASSMENT:"尴尬",
            WORRY:"担忧",
            FRUSTRATION:"受挫",
            DELIGHT:"愉快",
            WatchPerform:"观看表演",
            AbandonedGuildhallPetition:"放弃市政厅申请",
            AcceptedGuildhallPetition:"接受市政厅申请",
            ANGER:"愤怒",
            SHAME :"羞耻",
            RELIEF:"宽慰",
            SHAKEN :"动摇",
            RAPTURE:"狂喜",
            MajorInjuries:"损伤",
            DrinkWithoutCup:"没杯子喝饮料",
            DiscussProblems:"讨论问题",
            GRATITUDE :"感激",
            GoodDrink:'好饮料',
            ANNOYANCE:"烦恼",
            MORTIFICATION :"屈辱",
            Trauma:"创伤",
            Spar:"拳击",
            Uncovered:"裸露",
            Complained:"抱怨",
            NoShirt:"没有衬衫",
            remembered_longterm: "长期记忆",
            NeedsUnfulfilled: "需求未满足",
            INTEREST: "兴趣",
            IntellectualDiscussion:"智力讨论",
            Waterfall: "瀑布",
            SatisfiedAtWork:"满意工作",
            SATISFACTION:"满足",
            CONTENTMENT: "知足",
            BLISS: "狂喜",
            BOREDOM: "厌倦",
            Syndrome:'综合征',
            PLEASURE: "欢愉",
            AdmireArrangedBuilding:"赞赏建筑",
            AdmireBuilding:"赞赏建筑",
            Argument:"争论",
            WONDER: "奇妙",
            AdmireOwnBuilding: "欣赏自己建筑",
            LONELINESS : "孤独",
            PrayedDedicatedTemple: "祈祷",
            BedroomQuality: "豪华卧室",
            EUPHORIA: "兴奋",
            FONDNESS: "喜爱",
            DEJECTION : "沮丧",
            UNEASINESS: "不安",
            GoodMeal: "大餐",
        }
        let dfDiv = document.querySelector("#dfList");

        let btnSortName = document.querySelector("#sortName");
        let btnSortNameFlag = false;
        let btnSortAge = document.querySelector("#sortage");
        let btnSortAgeFlag = false;
        let btnSortStress = document.querySelector("#sortStress");
        let btnSortStressFlag = false;
        
        let btnSortSkill = document.querySelector("#sortSkill");
        
        let btnSortSmelt = document.querySelector("#sortsmelt");
        let btnSortSmeltFlag = false;

        let sortfight = document.querySelector("#sortfight");
        let sortfightFlag = false;


        let hideItems = document.querySelector("#hideItems");
        let hideSkill = document.querySelector("#hideSkill");
        let hideEmo = document.querySelector("#hideEmo");
        hideSkill.addEventListener("click", () => {
            let skillEls = document.querySelectorAll(".dfSkillCard");
            if (skillEls && skillEls.length) {
                skillEls.forEach(el => {
                    el.classList.toggle("hide")
                });
            }
        });
        hideItems.addEventListener("click", () => {
            let skillEls = document.querySelectorAll(".dfItemCard");
            if (skillEls && skillEls.length) {
                skillEls.forEach(el => {
                    el.classList.toggle("hide")
                });
            }
        });
        hideEmo.addEventListener("click", () => {
            let skillEls = document.querySelectorAll(".dfEmoCard");
            if (skillEls && skillEls.length) {
                skillEls.forEach(el => {
                    el.classList.toggle("hide")
                });
            }
        });
        
        btnSortName.addEventListener("click", () => {
            btnSortNameFlag = !btnSortNameFlag;
            renderData({
                sortFun: btnSortNameFlag? (arr)=> {
                    return arr.sort((a,b)=>getnamePoint(a.desName)-getnamePoint(b.desName));
                }:(arr)=> {
                    return arr.sort((b,a)=>getnamePoint(a.desName)-getnamePoint(b.desName));
                }
            });
        });

        btnSortSmelt.addEventListener("click", () => {
            btnSortSmeltFlag = !btnSortSmeltFlag;
            renderData({
                sortFun:btnSortSmeltFlag?arr => {
                    return arr.sort((a, b) => skillSmelt(a.jobSkill) - skillSmelt(b.jobSkill));
                }:arr => {
                    return arr.sort((b, a) => skillSmelt(a.jobSkill) - skillSmelt(b.jobSkill));
                }
            });
        });

        function getnamePoint(name) {
            let p = -9999999999;
            if(/(\d+)/.test(name)){
                p = RegExp.$1-0;
            }
            return p
        }
        
        btnSortStress.addEventListener("click", () => {
            btnSortStressFlag = !btnSortStressFlag;
            renderData({
                sortFun:btnSortStressFlag?arr => {
                    return arr.sort((a, b) => a.stressLevel - b.stressLevel);
                }:arr => {
                    return arr.sort((b, a) => a.stressLevel - b.stressLevel);
                }
            });
        });
        btnSortAge.addEventListener("click", () => {
            btnSortAgeFlag = !btnSortAgeFlag;
            renderData({
                sortFun:btnSortAgeFlag?arr => {
                    return arr.sort((a, b) => a.trueage - b.trueage);
                }:arr => {
                    return arr.sort((b, a) => a.trueage - b.trueage);
                }
            });
        });
        btnSortSkill.addEventListener("click", () => {
            let ipt = document.querySelector("#normal")
            let skill = ipt.value.trim()
            ipt.value = ""
            if(skill && skill != "") {
                renderData({
                    sortFun(arr) {
                        let skillType; // Swimming
                        Object.prototype.hasOwnProperty
                        for (let stype in arr[0].jobSkill) {
                            if(arr[0].jobSkill[stype].hasOwnProperty(skill)) {
                                skillType=stype
                                break
                            }
                        }
                        if(skillType){
                            return arr.sort((b,a) => {
                                return a.jobSkill[skillType][skill] - b.jobSkill[skillType][skill]
                            });
                        }
                    }
                });


            }
        });

        sortfight.addEventListener("click", () => {
            sortfightFlag = !sortfightFlag;   //
            renderData({
                sortFun:sortfightFlag?arr => {
                    return arr.sort((a, b) => skillPointMilitary(a.jobSkill) - skillPointMilitary(b.jobSkill));
                }:arr => {
                    return arr.sort((b, a) => skillPointMilitary(a.jobSkill) - skillPointMilitary(b.jobSkill));
                }
            });
        });
        
        function skillPointMilitary(skill) { // Military
            let p = 0;

            // MilitaryWeapon
            let militaryWeaponArr = Object.entries(skill.MilitaryWeapon)
            militaryWeaponArr = militaryWeaponArr.sort((a,b)=>b[1]-a[1]);
            let militaryWeaponPoint = militaryWeaponArr[0][1]**2
            
            let defencePoint = skill.MilitaryDefense.Armor**1.2 + skill.MilitaryDefense.Dodging**1.8 + skill.MilitaryDefense.Shield**1.2
             
            let MilitaryAttackPoint = skill.MilitaryAttack.Archery > skill.MilitaryAttack.Fighting? skill.MilitaryAttack.Archery**2.5 : skill.MilitaryAttack.Fighting**2.5
            
            p += militaryWeaponPoint + defencePoint + MilitaryAttackPoint
            // for (let key in skill) {
            //     if(/Military/ig.test(key)) {
            //         for (let key2 in skill[key]) {
            //             p += skill[key][key2]
            //         }
            //     }
            // }

            return p;
        }

        function skillSmelt(skill) {
            let p = 0;
            p += (skill.Normal.Weaponsmithing || 0) - 0;
            p += (skill.Normal.Armorsmithing || 0) - 0;
            return p;
        }

        renderData()
        
        
        
        
    
        async function renderData (props) {
            let data = await fetchData();
            if(props?.sortFun) {
                data = props.sortFun(data)||data
            }


            // get arr name min max
            let nums = [];
            data.forEach(v => {
                if(/(\d+)/.test(v.desName)) {
                    nums.push(RegExp.$1-0)
                }
            });
            if(nums && nums.length) {
                nums = nums.sort((a,b)=>a-b)
                let n = nums[0];
                let lackNum = [];
                nums.forEach((v,i) => {
                    if(v != n) {
                        
                        while(v>n){
                            lackNum.push(n)
                            n++
                        }
                        if(n > v){ n = v }
                        n++
                    } else {
                        n++
                    }
                });
                if(lackNum && lackNum.length) {
                    document.querySelector("#lack").innerHTML = "缺少编号："+lackNum.join(" ")
                }
            }


            document.querySelector("#counts").innerHTML = `总共${data.length}普通居民 `
            dfDiv.innerHTML = render(data)
            console.log(data)
        };







        function render (arr) {
            let html = "";

            arr.forEach(v => {

                html += `<div class="dfItem">
                    <div class="dfNameCard">
                        <div>${v.desName}</div>
                        <div>
                            心情:${v.stressLevel} &nbsp;
                            压力:${v.stress} &nbsp;
                            年龄${v.age} ${v.age==v.trueage? "": `真实年龄:${v.trueage}`} &nbsp;
                            ${v.isCraze?"Craze":""}
                            ${v.isZuzou?"Zuzou":""}
                            ${v.isVampire?"Vampire":""}
                        </div>
                    </div>
                    ${renderItems(v.items)}
                    ${renderEmos(v.emoStr)}
                    ${renderSkill(v.jobSkill)}
                </div>`;
            });


            return html;
        }
        
        function formatEmoFlag (flag) {
            return Enums[flag]||flag
        }
        function renderEmos(emos) {
            let html = `<div class="dfEmoCard"><div class="emoDetail">`;

            emos.forEach(emo => {
                if (emo.value != 0) {
                    html += `<div class="emodes"> ${emo.value + " " + (Enums[emo.type]||emo.type) + emo.strength + "("+(Enums[emo.thought]||emo.thought) + ") " + emo.flags?.filter(v=>v&&v!="unk2").map(v => formatEmoFlag(v)).join(",")} </div>`;
                }
            });

            return html + "</div></div>";
        }

        function renderItems(items) {
            let html = `<div class="dfItemCard"><div class="skillType">物品</div><div class="skillDetail">`;

            items.forEach(v => {
                html += `<div class="skilldes"> ${v} </div>`;
            });

            return html + "</div></div>";
        }

        function renderSkill(skill) {
            let html = "";

            for (let skillType in skill) {
                html += `
                    <div class="dfSkillCard">
                        <div class="skillType">${skillType}</div>
                        <div class="skillDetail">
                            ${Object.entries(skill[skillType]).filter(v=>v[1]>0).map(item => {
                                return `<div class="skilldes"> ${item[0]}: ${item[1]} </div>`
                            }).join("\n")}
                        </div>
                    </div>
                `;
            }

            return html;
        }

        async function fetchData () {
            let data = await fetch("http://localhost:6018/api/dfData");
            if(data.status == 200) {
                return data.json()
            } else {
                console.log("获取接口错误")
            }
        }



    </script>
</body>
</html>